<!DOCTYPE html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>

    <!-- *** I only test compatibility in Chrome/Safari base on Mac OSX ! *** -->
    <!-- some code copy from https://github.com/hakobera/Simple-WebSocket-Client. Thanks hakobera ! -->


    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <title>Android Remote Logcat</title>
    <style type="text/css">
        html, body, div, span, object, iframe,
        h1, h2, h3, h4, h5, h6, p, blockquote, pre,
        abbr, address, cite, code,
        del, dfn, em, img, ins, kbd, q, samp,
        small, strong, sub, sup, var,
        b, i,
        dl, dt, dd, ol, ul, li,
        fieldset, form, label, legend,
        table, caption, tbody, tfoot, thead, tr, th, td,
        article, aside, canvas, details, figcaption, figure,
        footer, header, menu, nav, section, summary,
        time, mark, audio, video {
        margin: 0;
        padding: 0;
        border: 0;
        outline: 0;
        font-size: 100%;
        vertical-align: baseline;
        background: transparent;

        }

        html, body {
        line-height: 1;
        height: 100%;
        }

        abbr[title], dfn[title] {
        border-bottom: 1px dotted #000;
        cursor: help;
        }

        table {
        border-collapse: collapse;
        border-spacing: 0;
        }

        ul#tabs {
        list-style-type: none;
        margin: 30px 0 0 0;
        padding: 0 0 0.3em 0;
        }

        ul#tabs li {
        display: inline;
        }

        ul#tabs li a {
        color: #42454a;
        background-color: #dedbde;
        border: 1px solid #c9c3ba;
        border-bottom: none;
        padding: 0.3em;
        text-decoration: none;
        }

        ul#tabs li a:hover {
        background-color: #f1f0ee;
        }

        ul#tabs li a.selected {
        color: #000;
        background-color: #f1f0ee;
        font-weight: bold;
        padding: 0.7em 0.3em 0.38em 0.3em;
        }

        div.tabContent {
        height: 65%;
        border: 1px solid #c9c3ba;
        padding: 0.5em;
        background-color: #f1f0ee;
        }

        div.tabContent.hide {
        display: none;
        }

        input, select {
        vertical-align: middle;
        }

        body {
        width: 100%;
        color: #000;
        height: 100%;
        background-color: #eee;
        font-size: 10pt;
        }

        fieldset {
        margin-bottom: 10px;
        padding: 5px 10px;
        border: 1px solid #777;
        }

        legend {
        padding: 0 5px;
        color: #777;
        font-size: 11pt;
        font-weight: bold;
        }

        label {
        color: #777;
        font-weight: bold;
        }

        #connectionStatus {
        font-weight: bold;
        }

        #content {
        padding: 10px;
        height: 100%;
        }

        #serverUrl {
        width: 300px;
        padding: 1px 3px;
        border: 1px solid #999;
        }

        #disconnectButton {
        display: none;
        }

        #requestArea textarea {
        min-width: 330px;
        height: 2em;
        padding: 0 3px;
        line-height: 150%;
        }

        #messageArea {
        height: 100%;
        }

        #messages {
        height: 92%;
        margin: 5px 0;
        padding: 0 5px;
        overflow: auto;
        border: 1px dotted #777;
        background-color: #fff;
        line-height: 150%;
        }

        #messages pre {
        width: 100%;
        color: #000;
        }

        #messages pre.sent {
        color: #f63;
        }

        #messages pre.V_log {
        color: black;
        }

        #messages pre.D_log {
        color: black;
        }

        #messages pre.I_log {
        color: black;
        }

        #messages pre.W_log {
        color: #FFC125;
        }

        #messages pre.E_log {
        color: red;
        }

        #messages pre.A_log {
        color: red;
        }

        #filelist {
        height: 92%;
        margin: 5px 0;
        padding: 0 5px;
        overflow: auto;
        border: 1px dotted #777;
        background-color: #fff;
        line-height: 150%;
        }
        #filelist a{
        font-size: large;
        margin-top: 5px;
        margin-bottom: 5px;
        }
    </style>

</head>
<body>
<script>
    if (!window.WebSocket && window.MozWebSocket) {
        window.WebSocket = window.MozWebSocket;
    } else if (!window.WebSocket) {
        alert("WebSocket not supported by this browser");
    }
</script>
<div id="content">
    <fieldset>
        <legend>Server Location</legend>
        <div>
            <label>URL:</label>
            <input type="text" id="serverUrl" value="ws://172.26.130.221:11229/logcat"/>
            <button id="connectButton">Open</button>
            <button id="disconnectButton">Close</button>
        </div>
        <div>
            <label>Status:</label>
            <span id="connectionStatus" style="color: red;">CLOSED</span>
        </div>
    </fieldset>
    <fieldset id="requestArea">
        <legend>Request</legend>
        <div>
            <textarea id="sendMessage" disabled="disabled"></textarea>

            <select id="select_log_priority">
                <option value="V">Verbose</option>
                <option value="D">Debug</option>
                <option value="I">Info</option>
                <option value="W">Warn</option>
                <option value="E">Error</option>
                <option value="A">Assert</option>
            </select>

        </div>
        <div>
            <button id="sendButton" disabled="disabled">Send</button>
            [Shortcut] Ctr + Enter
        </div>

    </fieldset>


    <ul id="tabs">
        <li><a href="#logcat">Logcat</a></li>
        <li><a href="#fileExplore">File Explore</a></li>
        <li><a href="#shell">Shell</a></li>
    </ul>

    <div class="tabContent" id="logcat">

        <button id="clearMessage">Clear</button>
        <div id="messages"></div>

    </div>

    <div class="tabContent" id="fileExplore">
        <button id="fileRefresh">Refresh</button>
        <div id="filelist">

        </div>

    </div>

    <div class="tabContent" id="shell">
        <h2>shell</h2>

    </div>

</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script type="text/javascript">
    var logMap = new Map();
    logMap.set("V", "V_log");
    logMap.set("D", "D_log");
    logMap.set("I", "I_log");
    logMap.set("W", "W_log");
    logMap.set("E", "E_log");
    logMap.set("A", "A_log");


    var currLevel = 'V';


    new function () {
        var ws = null;
        var connected = false;

        var serverVersion = null;

        var baseURL;
        var serverUrl;
        var connectionStatus;
        var sendMessage;

        var connectButton;
        var disconnectButton;
        var sendButton;

        var logPrioritySelect;
        var fileList;

        window.onbeforeunload = function () {
            if (ws) {
                ws.close();
            }
            return null;
        }

        var open = function () {
            var url = serverUrl.val();

            var st=url.indexOf("//");
            baseURL=url.substring(st, url.indexOf("/",st+2)).replace("//","");

            ws = new WebSocket(url);
            ws.onopen = onOpen;
            ws.onclose = onClose;
            ws.onmessage = onMessage;
            ws.onerror = onError;

            connectionStatus.text('OPENING ...');
            serverUrl.attr('disabled', 'disabled');
            connectButton.hide();
            disconnectButton.show();
        }

        var close = function () {
            if (ws) {
                console.log('CLOSING ...');
                ws.close();
            }
            connected = false;
            connectionStatus.text('CLOSED');
            connectionStatus.css("color", "red");

            serverUrl.removeAttr('disabled');
            connectButton.show();
            disconnectButton.hide();
            sendMessage.attr('disabled', 'disabled');
            sendButton.attr('disabled', 'disabled');
            logPrioritySelect.attr('disabled', 'disabled');

        }

        var clearLog = function () {
            $('#messages').html('');
        }

        var onOpen = function () {
            console.log('OPENED: ' + serverUrl.val());
            connected = true;
            connectionStatus.text('OPENED');
            connectionStatus.css("color", "green");

            sendMessage.removeAttr('disabled');
            sendButton.removeAttr('disabled');
            logPrioritySelect.removeAttr('disabled');

            ws.send('Hello Server');
        };

        var onClose = function () {
            console.log('CLOSED: ' + serverUrl.val());
            ws = null;
            addMessage("websocked closed!", 'SENT');
            close();
        };

        var onMessage = function (event) {

            addMessage(event.data);
        };

        var onError = function (event) {
            console.error(event);
            alert("websocket connection " + serverUrl.val() + " has error !");
        }

        var addMessage = function (data, type) {
            var msg = $('<pre>').text(data);

            if (type === 'SENT') {
                msg.addClass('sent');
            }

            var lineType = 'V';
            try {
                //change text color
                var leve = findType(data);

                var cls = logMap.get(leve);
                if (cls) {
                    lineType = leve;
                    msg.addClass(cls);
                }

            } catch (err) {
            }

            var messages = $('#messages');
            var canShow = canDisplayLog(lineType);
            messages.append(msg);
            msg.data("type", lineType);

            var msgBox = messages.get(0);

            if (canShow) {
                msg.show();
            } else {
                msg.hide();
            }

            while (msgBox.childNodes.length > 1000) {
                msgBox.removeChild(msgBox.firstChild);
            }
            if (canShow) {
                msgBox.scrollTop = msgBox.scrollHeight;
            }

        }

        var reqFileList = function (absPath,dir) {
            reqFileList2 = reqFileList;

            var parent;
            if (fileList.data("parent_path")) {
                parent = fileList.data("parent_path") + "/";
            }

            var fileUrl = 'http://' + baseURL + '/?format=jsonp&action=list&dir=';
            if(absPath){
                fileUrl+=dir;

            }else{
                if (parent) {
                fileUrl += parent;
            }
            fileUrl += dir;
            }



            $.ajax(
                    {
                        type: 'get',
                        url: fileUrl,
                        dataType: 'jsonp',
                        jsonp: "callback",
                        success: function (data) {

                            fileList.html('');
                            fileList.data("parent_path", data.dir);
                            var currPath = $('<a>').html(data.dir).attr("href", "javascript:reqFileList2('" + data.dir + "')");
                            fileList.append(currPath);
                            currPath.scrollTop = currPath.scrollHeight;


                            fileList.append($("<br/>"));
                            fileList.append($("<pre>").text("-----dir-----"));
                            fileList.append($("<br/>"));


                            var c=$('<a>').text(' .. ').attr("href", "javascript:reqFileList2(true,'" + data.parent + "')");
                                fileList.append(c);
                                c.scrollTop = c.scrollHeight;
                                fileList.append($("<br/>"));

                            for (var i in data.dir_list) {
                                var c=$('<a>').text(data.dir_list[i]).attr("href", "javascript:reqFileList2(false,'" + data.dir_list[i] + "')");
                                fileList.append(c);
                                c.scrollTop = c.scrollHeight;

                                fileList.append($("<br/>"));

                                //cbr.scrollTop = cbr.scrollHeight;
                            }
                            fileList.append($("<br/>"));
                            fileList.append($("<br/>"));
                            fileList.append($("<pre>").text("-----file-----"));
                            fileList.append($("<br/>"));
                            for (var i in data.file_list) {
                                var c=$('<a>').text(data.file_list[i]).attr("href", "http://" + baseURL + "/?action=download&path=" + data.dir + "/" + data.file_list[i]);
                                fileList.append(c);
                                c.scrollTop = c.scrollHeight;

                                fileList.append($("<br/>"));
                                //cbr.scrollTop = cbr.scrollHeight;
                            }
                        },
                        error: function (e) {
                            console.log(e);
                        }
                    }
            );

        }

        WebSocketClient = {
            init: function () {
                serverUrl = $('#serverUrl');
                connectionStatus = $('#connectionStatus');
                sendMessage = $('#sendMessage');

                connectButton = $('#connectButton');
                disconnectButton = $('#disconnectButton');
                sendButton = $('#sendButton');

                logPrioritySelect = $("#select_log_priority");

                fileList = $("#filelist");

                logPrioritySelect.change(function () {
                    currLevel = $(this).children('option:selected').val();

                    changeLogPriority(currLevel);
                });

                connectButton.click(function (e) {
                    close();
                    open();
                });

                disconnectButton.click(function (e) {
                    close();
                });

                sendButton.click(function (e) {
                    var msg = $('#sendMessage').val();
                    addMessage(msg, 'SENT');
                    ws.send(msg);
                });

                $('#clearMessage').click(function (e) {
                    clearLog();
                });

                $("#fileRefresh").click(function (e) {
                    reqFileList('');
                });

                var isCtrl;
                sendMessage.keyup(function (e) {
                    if (e.which == 17) isCtrl = false;
                }).keydown(function (e) {
                    if (e.which == 17) isCtrl = true;
                    if (e.which == 13 && isCtrl == true) {
                        sendButton.click();
                        return false;
                    }
                });
            }
        };


        function canDisplayLog(type) {
            switch (currLevel) {
                case 'V':
                    return true;
                case 'D':
                    return type == 'D' || type == 'I' || type == 'W' || type == 'E' || type == 'A';
                case 'I':
                    return type == 'I' || type == 'W' || type == 'E' || type == 'A';
                case 'W':
                    return type == 'W' || type == 'E' || type == 'A';
                case 'E':
                    return type == 'E' || type == 'A';
                case 'A':
                    return type == 'A';
            }
            return true;
        }

        function findType(line) {
            var inx = line.indexOf('/');
            if (inx > 0) {
                return line.charAt(inx - 1);
            }
        }


        function changeLogPriority(priority) {

            var currCls = logMap.get(priority);
            if (currCls) {

                $('#messages').children().each(function () {
                    var type = $(this).data("type");
                    if (type && canDisplayLog(type)) {
                        $(this).show();
                        $(this).scrollTop = $(this).scrollHeight;

                    } else {
                        $(this).hide();
                    }
                });
            }
        }

    }


    var tabLinks = new Array();
    var contentDivs = new Array();

    function init() {

        var tabListItems = document.getElementById('tabs').childNodes;
        for (var i = 0; i < tabListItems.length; i++) {
            if (tabListItems[i].nodeName == "LI") {
                var tabLink = getFirstChildWithTagName(tabListItems[i], 'A');
                var id = getHash(tabLink.getAttribute('href'));
                tabLinks[id] = tabLink;
                contentDivs[id] = document.getElementById(id);
            }
        }

        var i = 0;
        for (var id in tabLinks) {
            tabLinks[id].onclick = showTab;
            tabLinks[id].onfocus = function () {
                this.blur()
            };
            if (i == 0) tabLinks[id].className = 'selected';
            i++;
        }

        var i = 0;
        for (var id in contentDivs) {
            if (i != 0) contentDivs[id].className = 'tabContent hide';
            i++;
        }
    }

    function showTab() {
        var selectedId = getHash(this.getAttribute('href'));

        for (var id in contentDivs) {
            if (id == selectedId) {
                tabLinks[id].className = 'selected';
                contentDivs[id].className = 'tabContent';
            } else {
                tabLinks[id].className = '';
                contentDivs[id].className = 'tabContent hide';
            }
        }
        return false;
    }

    function getFirstChildWithTagName(element, tagName) {
        for (var i = 0; i < element.childNodes.length; i++) {
            if (element.childNodes[i].nodeName == tagName) return element.childNodes[i];
        }
    }

    function getHash(url) {
        var hashPos = url.lastIndexOf('#');
        return url.substring(hashPos + 1);
    }

    var reqFileList2;

    $(function () {
        WebSocketClient.init();
        init();

    });

</script>
</body>
</html>
